(function($){

    var sendPageReq = function(page,applyName, call){
        var mask = $('<div style="position: fixed;left: 0px;right: 0px;top: 0px;bottom: 0px;background: #000;z-index: 999;opacity: 0.3;"></div>');
        $('body').append(mask);
        var pageReq = {};
        $.extend(pageReq, page.data);
        if(pageReq.page){
            pageReq.page--;
        } else {
            pageReq.page = 0;
        }
        $.ajax({url:page.action,type:"get",cache:false,data:pageReq,
            success:function(ret){
                mask.remove();
                var pageData = {
                    page:1,//当前页
                    prev:1,//上一页
                    next:1,//下一页
                    totalPages:1,//总页数
                    totalElements:0,//总条数
                    size:10//每页条数
                };
                if(ret.obj){
                    if(ret.obj.number) pageData.page = ret.obj.number+1;
                    if(ret.obj.size) pageData.size = ret.obj.size;
                    if(ret.obj.totalElements) pageData.totalElements = ret.obj.totalElements;
                    if(ret.obj.totalPages) pageData.totalPages = ret.obj.totalPages;
                    pageData.prev = pageData.page-1;
                    pageData.next = pageData.page+1;

                    var content = ret.obj.content
                    var flag = false;
                    if(content){
                        flag = applyLocalFunc(applyName, [content, function () {
                            call.apply(null, [pageData, content])
                        }], true)

                    }

                    if(!flag){
                        if(call){
                            call.apply(null, [pageData, content])
                        }
                    }
                }

            }, error:function(){
                mask.remove();
            }
        });
    }




    var initHtml = function(that, page){
        var pageHtml = '<div class="table-page">'+
            '<div class="pagination-goto pagination-left" style="float:left;">'+
                '<button class="all-btn" data="csv">全部导出</button>'+
            '</div>'+
            '<div class="pagination-goto">'+
                '<input type="text" class="goto-text" value="{page}"/> '+
                '<button class="goto-btn">GO</button>'+
            '</div>'+
            '<ul class="pagination">'+
                '<li class="page-left" data="1">‹‹</li>'+
                '<li class="page-left" data="{prev}">‹</li>'+
                '<li class="active disabled">{page}</li>'+
                '<li class="page-right" data="{next}">›</li>'+
                '<li class="page-right" data="{totalPages}">››</li>'+
            '</ul>'+
            '<div class="pagination-info">'+
                '共有{totalElements}条， 每页显示：<input type="text" class="page-size" value="{size}"/> 条'+
            '</div>'+
            '</div>';

        sendPageReq(page, page.success, function(pageData, content){
            var ts = pageHtml.match(/\{(\S*)\}/g);
            for(var i=0;i<ts.length;i++){
                var key = ts[i].replace(/\{|\}/g, "");
                var reg = new RegExp(ts[i], "g")
                pageHtml = pageHtml.replace(reg, pageData[key]);
            }
            var pageThat = $(pageHtml);

            if(pageData.page<=1){
                pageThat.find(".pagination .page-left").addClass("disabled");
            }
            if(pageData.page>=pageData.totalPages){
                pageThat.find(".pagination .page-right").addClass("disabled");
            }
            //每页显示数量
            pageThat.find(".page-size").change(function(){
                if(isNaN($(this).val())){
                    $(this).val(pageData.size);
                } else {
                    pageData.size = $(this).val();
                    nextPage(that, page, pageData);
                }
            });
            //跳转页数
            pageThat.find(".goto-text").change(function(){
                if(isNaN($(this).val())){
                    $(this).val(pageData.page);
                }
            });
            pageThat.find(".goto-btn").click(function(){
                var val = pageThat.find(".goto-text").val();
                if(parseInt(val)>pageData.totalPages){
                    val = pageData.totalPages;
                }
                pageData.page=val;
                nextPage(that, page, pageData);
            });
            pageThat.find(".pagination li").not(".disabled").click(function(){
                var data = $(this).attr("data");
                pageData.page= parseInt(data);
                nextPage(that, page, pageData);
            });

            if(page.btnMap){
                for(var k in page.btnMap){
                    var btn = $('<button class="all-btn">'+k+'</button>');
                    btn.click(function(){
                        applyLocalFunc(page.btnMap[k], [content]);
                    });
                    pageThat.find(".pagination-left").append(btn);
                }
            }

            if(page.btnsMap){
                for(var k in page.btnsMap){
                    var btn = $('<button class="all-btn">'+k+'</button>');
                    btn.click(function(){
                        exportMain(page, '', page.btnsMap[k]);
                    });
                    pageThat.find(".pagination-left").append(btn);
                }
            }

            if(page.csvTitle){
                pageThat.find(".all-btn[data='csv']").click(function(){
                    exportMain(page, 'csv', page.csvApply);
                });
            } else {
                pageThat.find(".all-btn[data='csv']").hide();
            }
            $(that).html(pageThat);

        });
    }


    var isPageDownload = false;
    var index = 1;
    var mask = null;
    var exportMain = function(page, type, applyName){
        mask = $('<div class="page-download">\n' +
            '\t\t\t<div class="page-download-mask"></div>\n' +
            '\t\t\t<div class="page-download-main">\n' +
            '\t\t\t\t<div class="page-download-content">\n' +
            '\t\t\t\t\t<div class="page-download-progress">\n' +
            '\t\t\t\t\t\t<div class="page-download-percent"></div>\n' +
            '\t\t\t\t\t</div>\n' +
            '\n' +
            '<div class="page-download-text"></div>'+
            '\t\t\t\t\t<button class="page-download-but">中断</button>\n' +
            '\n' +
            '\t\t\t\t</div>\n' +
            '\t\t\t</div>\n' +
            '\t\t</div>');

        mask.find(".page-download-but").click(function(){
            isPageDownload = true;
        })
        $("body").append(mask);
        page.data.page = 1;
        page.data.size = 200;
        var list = "";
        index = 1;
        exportCsv(page, mask, type, applyName, list, function(list){

            isPageDownload = false;
            mask.remove();
        });
    }

    var exportCsv = function(page, mask, type,applyName, list, call){
        if(type == 'csv'){
            if(!list){
                for(var key in page.csvTitle){
                    if(list){
                        list += ","+page.csvTitle[key];
                    } else {
                        list += page.csvTitle[key];
                    }
                }
                list+=escape("\n");
            }
        }

        sendPageReq(page, applyName, function(pageData, content){
            if(type == 'csv' && list != null){
                for(var i=0;i<content.length;i++){
                    var obj = content[i];
                    var line = null;
                    for(var k in page.csvTitle){
                        var key = k;
                        var value = (obj[key]==null)?"":obj[key];
                        if(obj && obj[key] && typeof(obj[key]) == 'string')
                            value = obj[key].replace(/,/g, "，").replace(/\n/g, " ").replace(/'/g, "‘").replace(/"/g, "“").replace("#", "");
                        if(line!=null){
                            line += ","+value;
                        } else {
                            line = value;
                        }
                    }
                    line+=escape("\n");
                    list+=line;
                }
            }
            mask.find(".page-download-percent").css("width", pageData.page/pageData.totalPages*100+"%")
            mask.find(".page-download-text").html("已处理 "+(pageData.page*pageData.size)+"条("+(pageData.page/pageData.totalPages*100).toFixed(2)+"%)");
            if(type == 'csv' && (list.length>320000 || pageData.page>=pageData.totalPages || isPageDownload)){
                var href = "data:text/csv;charset=utf-8,\ufeff" + list;
                if (window.navigator.msSaveOrOpenBlob) {
                    href = "\ufeff"+list;
                }
                if (window.navigator.msSaveOrOpenBlob) {
                    var blob = new Blob([decodeURIComponent(encodeURI(href))], {
                        type: "text/csv;charset=utf-8;"
                    });
                    navigator.msSaveBlob(blob, page.csv+"_"+index+'.csv');
                }else{
                    var link = document.createElement("a");
                    link.setAttribute("href", href);
                    link.setAttribute("download", page.csv+"_"+index+".csv");
                    document.body.appendChild(link);
                    link.click();
                    $(link).remove();
                }
                list = "";
                index++;
            }

            if(pageData.page<pageData.totalPages && !isPageDownload){
                page.data.page++;
                exportCsv(page, mask,type,applyName, list, call);
            } else {
                call.apply(null, [list])
            }
        });
    }


    var nextPage = function(that, page, pageData){
        if(pageData.page<0)
            pageData.page = 0;
        if(pageData.totalPages<pageData.page)
            pageData.page = pageData.totalPages;
        page.data.page = parseInt(pageData.page);
        page.data.size = pageData.size;
        initHtml(that, page);
    }

    var pageBtn = function(obj, btnName, applyName, that, page){
        var k = obj.name;
        if(k){
            var value = obj.value;
            var index = '';
            var btnNames = btnName+"s";
            var applyNames = applyName+"s";
            if(k.indexOf("data-page-"+btnNames) != -1){
                if(!page.btnsMap)
                    page.btnsMap = {};
                if(k != 'data-page-'+btnNames){
                    index = k.replace("data-page-"+btnNames, "");
                }
                var funcName = $(that).attr("data-page-"+applyNames+index)
                page.btnsMap[value] = funcName;
            } else if(k.indexOf("data-page-"+btnName) != -1){
                if(!page.btnMap)
                    page.btnMap = {};
                if(k != 'data-page-'+btnName){
                    index = k.replace("data-page-"+btnName, "");
                }
                var funcName = $(that).attr("data-page-"+applyName+index)
                page.btnMap[value] = funcName;
            }

        }
    }


    var pages = {};
    var main = function(){
        $("[data-page-action]").each(function(){
            if(checkLoadElement(this)){
                return;
            }
            var page = {that:this,action:null,success:null,csvApply:null,data:{size:10,page:1},btnMap:null,btnsMap:null,csv:"", csvTitle:null};
            var name = $(this).attr("data-page");
            if(pages[name]){
                return;
            }
            pages[name] = page;
            page.action = getInitData($(this).attr("data-page-action"));
            page.csv = getInitData($(this).attr("data-page-csv"), new Date().getTime());
            page.success = getInitData($(this).attr("data-page-success"));
            page.csvApply = getInitData($(this).attr("data-page-csv_apply"));

            var pageData = getInitData($(this).attr("data-page-data"));

            if(pageData){
                var data = pageData.split("&");
                for(var i=0;i<data.length;i++){
                    if(data[i]){
                        var k = data[i].split("=")[0];
                        var v = data[i].replace(k+"=", "");
                        v = v.replace(/'/g, "")
                        page.data[k] = v;
                    }
                }
            }
            var csv_title = getInitData($(this).attr("data-page-csv_title"));
            if(csv_title){
                var csvTitles = csv_title.split(",");
                page.csvTitle = {};
                for(var i=0;i<csvTitles.length;i++){
                    var name = csvTitles[i].match(/\([^(]+\)/g)
                    if(name){
                        name = name[0];
                    } else {
                        name = "";
                    }
                    var filed = csvTitles[i].replace(name, "")
                    name = name.replace(/\(|\)/g, "");
                    if(!name){
                        name = filed;
                    }
                    page.csvTitle[filed] = name;
                }
            }


            for (var key in this.attributes) {
                var obj = this.attributes[key];
                pageBtn(obj, "btn", "apply", this, page);


            }

            removeSysKey(this);
            initHtml(this, page);
        });
    }

    //检测是否已经加载
    var loadElements = [];
    var checkLoadElement = function(that){
        var flag = false;
        for(var i=0;i<loadElements.length;i++){
            if($(that).is($(loadElements[i]))){
                flag = true;
            }
        }
        if(!flag){
            loadElements[loadElements.length] = that;
        }
        return flag;
    }

    //删除系统属性
    var removeSysKey = function(that){
        var removeKey = [];
        for (var key in that.attributes) {
            var value = that.attributes[key];
            if (value.name && value.name.indexOf("data-page") != -1) {
                removeKey[removeKey.length] = value.name;
            }
        }
        for (var j = 0; j < removeKey.length; j++) {
            $(that).removeAttr(removeKey[j]);
        }
    }

    //解析初始化数据
    var getInitData = function(attrValue, defaultValue){
        if(attrValue){
            var reg = /{[^{]+}/g;
            var attrs = attrValue.match(reg)
            if(attrs){
                for(var i=0;i<attrs.length;i++){
                    var bl = attrs[i].replace(/{|}/g, "");
                    attrValue = attrValue.replace(attrs[i], (window[bl]==null)?'':window[bl]);
                }
            }
        } else {
            attrValue = defaultValue;
        }
        return attrValue;
    }

    /**
     *
     * @param func  本地函数 函数规则 $.xxx(...)
     * @param data  传入数据
     * @param useRetFlag 是否使用自定义返回数据
     * @returns {*}
     */
    var applyLocalFunc = function(func, data, useRetFlag){
        if(func) {
            var reg = /\$\.\w+\([^\(]*\)/g;
            if(reg.test(func)){
                var z = func.match(reg);
                for(var i=0;i< z.length;i++){
                    var newZ = z[i].replace("$.", "").replace("(", ",").replace(")", "");
                    var newZSons = newZ.split(",");
                    var v = window[newZSons[0]];
                    if(!v)
                        return false;
                    var funValues = [];
                    for(var j=0;j<newZSons.length;j++){
                        if(j > 0 && newZSons[j] !== ''){
                            funValues[funValues.length] = newZSons[j].replace(/'/g, "");
                        }
                    }
                    for(var j=0;j<data.length;j++){
                        funValues[funValues.length] = data[j];
                    }
                    if(useRetFlag){
                        return v.apply(null, funValues);
                    } else{
                        v.apply(null, funValues);
                        return true;
                    }

                }

            }
        }
        return false
    }

    $.extend({
        pageReload:function(name, reqData) {
            var page = pages[name];
            if(page){
                if(reqData){
                    $.extend(page.data, reqData);
                }
                initHtml(page.that, page);
            }

        }
    });

    $(document).ready(function(){
        main();

        $("body").bind('DOMNodeInserted', function(e) {
            var that = $(e.target);
            var fromAction = $(that).attr("data-page-action");
            if(fromAction!=null){
                main();
            } else {
                if(that.find("[data-page-action]").length>0){
                    main();
                }
            }
        });
    });
})(jQuery);
